#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <assert.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <semaphore.h>

//mis funciones
//#include "servicio_conn.c"

//Shared Mem
#include <sys/shm.h>
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
	int listen_fd, connfd, fd;
	struct sockaddr_in listen_conn;

	char buf[1024];					//buffer de lectura del archivo de configuracion
	int n = 0, max_childs, port;			//variables del archivo de configuracion

	sem_t * sem;
	
	/* Memoria Compartida */
	key_t shm_key;
	int id_mem;
	char *mem = NULL;
	int i,j;
	
	shm_key = ftok ("/bin/ls", 33);
	if (shm_key == -1)
	{
		printf("No consigo clave para memoria compartida");
		exit(EXIT_FAILURE);
	}

	id_mem = shmget (shm_key, sizeof(char)*100, 0777 | IPC_CREAT);
	if (id_mem == -1)
	{
		printf("No consigo Id para memoria compartida");
		exit(EXIT_FAILURE);
	}

	mem = (char*)shmat (id_mem, (char *)0, 0);
	if (mem == NULL)
	{
		printf("No consigo memoria compartida");
		exit(EXIT_FAILURE);
	}
	
	printf("Memoria compartida creada %d \n", id_mem);
	/* Memoria Compartida */
	
	assert(argc==2);

	max_childs = 5;
	
	port = atoi(argv[1]);
	printf("childs: %d\nport: %d\n\n", max_childs, port);


	listen_fd = socket(PF_INET, SOCK_STREAM, 0);
	
	listen_conn.sin_family = AF_INET;
	listen_conn.sin_port = htons(port); 		//htons para no tener problemas con la arquitectura
	listen_conn.sin_addr.s_addr = htonl(INADDR_ANY); //en cualquiera de mis IPs

	if(bind(listen_fd, (struct sockaddr *)&listen_conn, sizeof (listen_conn))==-1) {
		perror("bind()");
		//sem_unlink("/semaforo_child");
		exit(EXIT_FAILURE);
	}

	listen(listen_fd, 10);

	while((connfd = accept(listen_fd, NULL, 0)) != -1) {
		fprintf(stderr, "Conexion entrante: ");
		system("date");
		//sem_wait(sem);
		
		mem[n] = connfd;
		
		for (i = 0; i <= n; i++)
		{
			printf("%d \n", mem[i]);
		}

		n++;
				
		switch(fork()) 
		{
			case -1:
				//sem_unlink("/semaforo_child");
				perror("fork()");
				exit(EXIT_FAILURE);
			case 0:
				sleep(20);
				//servicio_conn(connfd);
				//sem_post(sem);
				_exit(EXIT_SUCCESS);
		}
	
		close(connfd); //cerramos la conexion del padre
	}
	//sem_unlink("/semaforo_child");
	perror("accept()");

	return EXIT_FAILURE;
}
